﻿using HlELock.Core;
using Prism.Commands;
using Prism.Mvvm;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows.Input;

namespace HlELock.Wpf.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private ObservableCollection<IUsbHid> _usbHids;

        public ObservableCollection<IUsbHid> UsbHids
        {
            get => _usbHids;
            set => SetProperty(ref _usbHids, value);
        }

        public MainWindowViewModel()
        {
            _usbHids = UsbHidHelper.GetDeviceList().ToObservableCollection();
            EncryptionDevice = new DeviceViewModel();
            CardDevice = new DeviceViewModel();

        }
        private DeviceViewModel _encryptionDevice;
        public DeviceViewModel EncryptionDevice
        {
            get { return _encryptionDevice; }
            set { SetProperty(ref _encryptionDevice, value); }
        }

        private DeviceViewModel _cardDevice;
        public DeviceViewModel CardDevice
        {
            get { return _cardDevice; }
            set { SetProperty(ref _cardDevice, value); }
        }
    }



    public class DeviceViewModel : BindableBase
    {
        private bool _isJoin = false;
        /// <summary>
        /// 是否已选择加密器
        /// </summary>
        public bool IsJoin
        {
            get { return _isJoin; }
            set
            {
                {
                    SetProperty(ref _isJoin, value);
                    RefreshStats();
                    State = IsJoin ? $"设备已连接,VID={CurrentDevice.VID}PID={CurrentDevice.PID} VER={CurrentDevice.VER}" : "设备尚未连接";
                }
            }
        }
        private bool _disableSelect = true;

        public bool DisableSelect
        {
            get { return _disableSelect; }
            set { SetProperty(ref _disableSelect, value); }
        }


        /// <summary>
        /// 刷新加密机区域状态
        /// </summary>
        private void RefreshStats()
        {
            DisableSelect = !IsJoin;
            ConnectCommand.RaiseCanExecuteChanged();
            DisconnectCommand.RaiseCanExecuteChanged();
            SendMessageCommand.RaiseCanExecuteChanged();
        }
        private DelegateCommand _connectCommand;
        public DelegateCommand ConnectCommand =>
            _connectCommand ?? (_connectCommand = new DelegateCommand(ExecuteConnectCommand, () => !IsJoin));

        /// <summary>
        /// 连接加密器
        /// </summary>
        void ExecuteConnectCommand()
        {
            if (CurrentDevice == null) return;
            CurrentDevice.OnReceiveMessaged += CurrentDevice_OnReceiveMessaged;
            CurrentDevice.OpenWithPath();
            IsJoin = true;
        }
        private void RefreshReturnData(byte[] obj = null)
        {
            if (obj == null)
            {
                ReturnDataString = ReturnData = string.Empty;
            }
            else
            {
                ReturnDataString = Encoding.ASCII.GetString(obj);
                ReturnData = string.Join("", obj.Select(s => s.ToString("X2")));
            }

        }
        private void CurrentDevice_OnReceiveMessaged(byte[] obj)
        {
            RefreshReturnData(obj);
        }

        private DelegateCommand _disconnectCommand;
        /// <summary>
        /// 断开加密器
        /// </summary>
        public DelegateCommand DisconnectCommand =>
            _disconnectCommand ?? (_disconnectCommand = new DelegateCommand(ExecuteDisconnectCommand, () => IsJoin));

        void ExecuteDisconnectCommand()
        {
            CurrentDevice.Close();
            IsJoin = false;
        }

        private string _state = "设备尚未连接";
        public string State
        {
            get { return _state; }
            set { SetProperty(ref _state, value); }
        }

        private UsbHid _currentDevice;
        public UsbHid CurrentDevice
        {
            get { return _currentDevice; }
            set { SetProperty(ref _currentDevice, value); }
        }

        private string _returnData;
        public string ReturnData
        {
            get { return _returnData; }
            set { SetProperty(ref _returnData, value); }
        }
        private string _returnDataString;

        public string ReturnDataString
        {
            get { return _returnDataString; }
            set { SetProperty(ref _returnDataString, value); }
        }
        private string _inputValue;
        public string InputValue
        {
            get { return _inputValue; }
            set { SetProperty(ref _inputValue, value); }
        }

        private DelegateCommand<string> _sendMessageCommand;
        public DelegateCommand<string> SendMessageCommand =>
            _sendMessageCommand ?? (_sendMessageCommand = new DelegateCommand<string>(ExecuteSendMessageCommand, s => IsJoin));
        private string _sendData;
        public string SendData
        {
            get { return _sendData; }
            set { SetProperty(ref _sendData, value); }
        }
        void ExecuteSendMessageCommand(string cmd)
        {
            RefreshReturnData();
            SendData = cmd + InputValue;
            CurrentDevice.SendMessage(SendData);
            InputValue = string.Empty;
        }
    }
}
